package com.github.common.extend.demo.config.json.jaskson.filter;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.github.common.extend.demo.config.json.ValueFormat;
import org.apache.commons.lang.StringUtils;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.regex.Pattern;

/**
 * 实现{@link ValueFormat}的功能
 * @author X1993
 * @date 2022/11/16
 * @description
 */
public class ValueFormatSerializer extends JsonSerializer<Object> implements ContextualSerializer {

    public final static String PLACEHOLDER = "{0}";

    private ValueFormat valueFormatAnnotation;

    private BeanProperty beanProperty;

    public ValueFormatSerializer() {
    }

    public ValueFormatSerializer(final ValueFormat valueFormatAnnotation, BeanProperty beanProperty) {
        this.valueFormatAnnotation = valueFormatAnnotation;
        this.beanProperty = beanProperty;
    }

    @Override
    public void serialize(final Object s, final JsonGenerator jsonGenerator,
                          final SerializerProvider serializerProvider) throws IOException
    {
        if (s != null && valueFormatAnnotation != null && beanProperty != null) {
            String str = s.toString();
            String patternStr = valueFormatAnnotation.pattern();
            boolean match = StringUtils.isEmpty(patternStr) ? true : Pattern.compile(patternStr).matcher(str).matches();
            if (match){
                String writeValue = valueFormatAnnotation.writeValue();
                if (StringUtils.isNotEmpty(writeValue)){
                    String writeValueStr = MessageFormat.format(writeValue ,s);
                    String writeProperty = valueFormatAnnotation.writeProperty();
                    if (StringUtils.isEmpty(writeProperty) || beanProperty.getName().equals(writeProperty)) {
                        jsonGenerator.writeString(writeValueStr);
                        return;
                    }

                    jsonGenerator.writeObject(s);
                    //将描述写入指定的新属性
                    jsonGenerator.writeObjectField(writeProperty ,writeValueStr);
                    return;
                }
            }
        }

        jsonGenerator.writeObject(s);
    }

    @Override
    public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
                                              final BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty == null) {
            // 为空直接跳过
            return serializerProvider.findNullValueSerializer(beanProperty);
        }
        ValueFormat valueFormat = beanProperty.getAnnotation(ValueFormat.class);
        if (valueFormat == null) {
            valueFormat = beanProperty.getContextAnnotation(ValueFormat.class);
        }
        if (valueFormat != null) {
            return new ValueFormatSerializer(valueFormat, beanProperty);
        }
        throw new IllegalStateException();
    }

}